﻿using System;
using System.Reflection;
using DiceRoller.Dice;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace DiceRollingTests
{
    [TestClass()]
    public class DieTests
    {
        [TestMethod()]
        public void ConstructorShouldSetMinimumValueToDefaultOf1()
        {
            var mock = new Mock<Die>(2);
            mock.CallBase = true;

            var die = mock.Object;

            Assert.AreEqual(1, die.MinimumValue);
            Assert.AreEqual(2, die.MaximumValue);
        }

        [TestMethod()]
        public void ConstructorShouldSetMaxAndMinValueWhenSupplied()
        {
            var mock = new Mock<Die>(1, 2);
            mock.CallBase = true;

            var die = mock.Object;

            Assert.AreEqual(1, die.MinimumValue);
            Assert.AreEqual(2, die.MaximumValue);
        }

        [TestMethod()]
        public void ConstructorShouldRequireMinValueGreaterThan0()
        {
            var mock = new Mock<Die>(MockBehavior.Loose, 0, 2);
            mock.CallBase = true;

            try
            {
                var die = mock.Object;
                Assert.Fail("Exception should have been thrown.");
            }
            catch (TargetInvocationException ex)
            {
                var exception = ex.InnerException as ArgumentOutOfRangeException;
                Assert.AreEqual("The minimum value '0' must be greater than zero.\r\nParameter name: minValue", exception.Message);
                Assert.AreEqual("minValue", exception.ParamName);
                Assert.IsNull(exception.ActualValue);
            }
        }

        [TestMethod()]
        public void ConstructorShouldRequireMaxValueGreaterThanMin()
        {
            var mock = new Mock<Die>(2, 1);
            mock.CallBase = true;

            try
            {
                var die = mock.Object;
                Assert.Fail("Exception should have been thrown.");
            }
            catch (TargetInvocationException ex)
            {
                var exception = ex.InnerException as ArgumentOutOfRangeException;
                Assert.AreEqual("The minimum value of '2' must be less than the supplied maximum value of '1'\r\nParameter name: minValue", exception.Message);
                Assert.AreEqual("minValue", exception.ParamName);
                Assert.IsNull(exception.ActualValue);
            }
        }
    }
}
